package com.wishu.finance.utils;

import com.ruoyi.common.core.utils.SpringUtils;
import com.wishu.finance.domain.WebCommonInfo;
import com.wishu.finance.enums.DeviceType;
import com.wishu.finance.enums.UserType;
import org.springframework.context.MessageSource;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * Miscellaneous utilities for web applications.
 *
 * @author L.cm
 */
public class WebUtils extends org.springframework.web.util.WebUtils {
    //移动设备Agent  
    private static final String phoneAgentReg =
            "\\bNokia|SAMSUNG|MIDP-2|CLDC1.1|SymbianOS|MAUI|UNTRUSTED/1.0"
                    + "|Windows CE|iPhone|iPad|Android|BlackBerry|UCWEB|ucweb|BREW|J2ME|YULONG|YuLong|COOLPAD|TIANYU|TY-"
                    + "|K-Touch|Haier|DOPOD|Lenovo|LENOVO|HUAQIN|AIGO-|CTC/1.0"
                    + "|CTC/2.0|CMCC|DAXIAN|MOT-|SonyEricsson|GIONEE|HTC|ZTE|HUAWEI|webOS|GoBrowser|IEMobile|WAP2.0\\b";
    private static final String tableAgentReg =
            "\\b(ipad|tablet|(Nexus 7)|up.browser"
                    + "|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";

    //移动设备正则匹配：手机端、平板  
    static Pattern phoneAgentPat = Pattern.compile(phoneAgentReg, Pattern.CASE_INSENSITIVE);
    static Pattern tableAgentePat = Pattern.compile(tableAgentReg, Pattern.CASE_INSENSITIVE);

    //线程本地变量
    private static final ThreadLocal<WebCommonInfo> webInfo = new ThreadLocal<WebCommonInfo>();

    /**
     * 判断是否ajax请求
     * spring ajax 返回含有 ResponseBody 或者 RestController注解
     *
     * @param handlerMethod HandlerMethod
     * @return 是否ajax请求
     */
    public static boolean isAjax(HandlerMethod handlerMethod) {
        ResponseBody responseBody = handlerMethod.getMethodAnnotation(ResponseBody.class);
        if (null != responseBody) {
            return true;
        }
        // 获取类上面的Annotation，可能包含组合注解，故采用spring的工具类
        Class<?> beanType = handlerMethod.getBeanType();
        responseBody = AnnotationUtils.getAnnotation(beanType, ResponseBody.class);
        if (null != responseBody) {
            return true;
        }
        return false;
    }

    /**
     * 读取cookie
     *
     * @param request
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String name) {
        Cookie cookie = getCookie(request, name);
        return cookie != null ? cookie.getValue() : null;
    }

    /**
     * 清除 某个指定的cookie
     *
     * @param response
     * @param key
     */
    public static void removeCookie(HttpServletResponse response, String key) {
        setCookie(response, key, null, 0);
    }

    /**
     * 设置cookie
     *
     * @param response
     * @param name
     * @param value
     * @param maxAgeInSeconds
     */
    public static void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
        Cookie cookie = new Cookie(name, value);
        cookie.setPath("/");
        cookie.setMaxAge(maxAgeInSeconds);
        cookie.setHttpOnly(true);
        response.addCookie(cookie);
    }


    public static boolean isMobileAgent(String agent) {
        if (agent == null) {
            return false;
        }
        return phoneAgentPat.matcher(agent).find();
    }

    public static void setDeviceType(DeviceType device) {
        getWebCommonInfo().setDeviceType(device);
    }

    public static DeviceType getDeviceType() {
        return getWebCommonInfo().getDeviceType();
    }

    public static void setRequest(HttpServletRequest request) {
        getWebCommonInfo().setRequest(request);
    }

    public static HttpServletRequest getRequest() {
        return getWebCommonInfo().getRequest();
    }

    public static void setUserType(UserType userType) {
        getWebCommonInfo().setUserType(userType);
    }

    public static UserType getUserType() {
        return getWebCommonInfo().getUserType();
    }

    public static WebCommonInfo getWebCommonInfo() {
        WebCommonInfo info = webInfo.get();
        if (info == null) {
            info = new WebCommonInfo();
            webInfo.set(info);
        }

        return info;
    }

    /**
     * 得到网站URL的根URL，
     * 例如：http://www.baidu.com    http://127.0.0.1:8080/test
     *
     * @return
     */
    public static String getWebBaseUrl() {
        HttpServletRequest request = getRequest();

        String port;
        if ("http".equals(request.getScheme().toLowerCase())) {
            if (request.getServerPort() == 80) {
                port = "";
            } else {
                port = ":" + request.getServerPort();
            }
        } else if ("https".equals(request.getScheme().toLowerCase())) {
            if (request.getServerPort() == 443) {
                port = "";
            } else {
                port = ":" + request.getServerPort();
            }
        } else {
            port = ":" + request.getServerPort();
        }

        return request.getScheme() + "://" + request.getServerName() + port + request.getContextPath();
    }

    /**
     * 通过相对网址拼接处完整的URL
     *
     * @param relativeUrl 例如：/Api/auctionItem
     * @return 完整URL，例如：http://localhost:8008/test/Api/auctionItem
     */
    public static String getFullUrl(String relativeUrl) {
        if (relativeUrl.charAt(0) == '/') {
            return getWebBaseUrl() + relativeUrl;
        } else {
            return getWebBaseUrl() + "/" + relativeUrl;
        }
    }

    /**
     * 通过完整地址取得站内的相对地址
     *
     * @param fullUrl 例如：http://localhost:8008/test/Api/auctionItem
     * @return 相对URL，例如：/Api/auctionItem
     */
    public static String getRelativeUrl(String fullUrl) {
        HttpServletRequest request = getRequest();
        String context = request.getContextPath();
        int idx = fullUrl.indexOf("://");
        if (idx == -1) {
            idx = 0;
        } else {
            idx += 4;
        }
        idx = fullUrl.indexOf('/', idx) + context.length();
        return fullUrl.substring(idx);
    }

    public static String getRequestDomain(HttpServletRequest request) {
        String url = request.getRequestURL().toString();
        int idx1 = url.indexOf("//");
        int idx2 = url.indexOf('/', idx1 + 2);
        int idx3 = url.indexOf(':', idx1 + 2);
        if (idx3 > 0 && idx3 < idx2) {
            return url.substring(idx1 + 2, idx3);
        } else {
            return url.substring(idx1 + 2, idx2);
        }
    }

    public static String getI18nMessage(String msgCode, String defaultMsg) {
        Locale locale = SpringUtils.getBean(LocaleResolver.class).resolveLocale(WebUtils.getRequest());
        return SpringUtils.getBean(MessageSource.class).getMessage(msgCode, null, defaultMsg, locale);
    }

    public static String getI18nMessage(String msgCode, Object[] args, String defaultMsg) {
        Locale locale = SpringUtils.getBean(LocaleResolver.class).resolveLocale(WebUtils.getRequest());
        return SpringUtils.getBean(MessageSource.class).getMessage(msgCode, args, defaultMsg, locale);
    }

    public static String getI18nMessage(String msgCode, Object[] args) {
        Locale locale = SpringUtils.getBean(LocaleResolver.class).resolveLocale(WebUtils.getRequest());
        return SpringUtils.getBean(MessageSource.class).getMessage(msgCode, args, locale);
    }

    public static String getI18nMessage(String msgCode, Object[] args, Locale locale) {
        return SpringUtils.getBean(MessageSource.class).getMessage(msgCode, args, locale);
    }
}
